﻿namespace System.ServiceModel.DomainServices.Client
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;

    public sealed class LoadOperation<TEntity> : LoadOperation where TEntity: Entity
    {
        private Action<LoadOperation<TEntity>> _cancelAction;
        private Action<LoadOperation<TEntity>> _completeAction;
        private ReadOnlyObservableCollection<TEntity> _entities;
        private ObservableCollection<TEntity> _entitiesCollection;

        internal LoadOperation(EntityQuery<TEntity> query, LoadBehavior loadBehavior, Action<LoadOperation<TEntity>> completeAction, object userState, Action<LoadOperation<TEntity>> cancelAction) : base(query, loadBehavior, userState)
        {
            this._entitiesCollection = new ObservableCollection<TEntity>();
            this._cancelAction = cancelAction;
            this._completeAction = completeAction;
        }

        protected override void CancelCore()
        {
            this._cancelAction((LoadOperation<TEntity>) this);
        }

        protected override void InvokeCompleteAction()
        {
            if (this._completeAction != null)
            {
                this._completeAction((LoadOperation<TEntity>) this);
            }
        }

        protected override void UpdateResults(DomainClientResult result)
        {
            base.UpdateResults(result);
            if (this._entities != null)
            {
                this._entitiesCollection.Clear();
                foreach (TEntity local in result.Entities)
                {
                    this._entitiesCollection.Add(local);
                }
            }
        }

        public IEnumerable<TEntity> Entities
        {
            get
            {
                if (this._entities == null)
                {
                    if ((base.Result != null) && base.Result.Entities.Any<Entity>())
                    {
                        foreach (TEntity local in base.Result.Entities)
                        {
                            this._entitiesCollection.Add(local);
                        }
                    }
                    this._entities = new ReadOnlyObservableCollection<TEntity>(this._entitiesCollection);
                }
                return this._entities;
            }
        }

        public EntityQuery<TEntity> EntityQuery
        {
            get
            {
                return (EntityQuery<TEntity>) base.EntityQuery;
            }
        }

        protected override bool SupportsCancellation
        {
            get
            {
                return (this._cancelAction != null);
            }
        }
    }
}

